﻿using System;
using UtilZ.Dotnet.Ex.ZLog;

namespace UtilZ.Dotnet.Ex.Base
{
    /// <summary>
    /// 自旋线程
    /// </summary>
    public class SpinThread : IDisposable
    {
        private readonly ThreadEx _thread;
        private readonly ISpinThreadAction[] _actions;
        private int _index = 0;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="count">自旋动作数量</param>
        /// <param name="name">线程名称</param>
        /// <param name="isBackground">后台运行标识[true:后台线程;false:前台线程]</param>
        public SpinThread(int count, string name = null, bool isBackground = true)
        {
            this._actions = new ISpinThreadAction[count];
            this._thread = new ThreadEx(this.SpinThreadMethod, name, isBackground);
        }

        private void SpinThreadMethod(ThreadPara threadPara)
        {
            try
            {
                while (!threadPara.Token.IsCancellationRequested)
                {
                    for (int i = 0; i < this._index; i++)
                    {
                        this._actions[i].Excute();
                    }
                }
            }
            catch (Exception ex)
            {
                ZLoger.Error(ex);
            }
        }

        /// <summary>
        /// 添加一个执行动作
        /// </summary>
        /// <param name="action">执行动作对象</param>
        public void AddAction(ISpinThreadAction action)
        {
            this._actions[this._index] = action;
            this._index++;
        }

        /// <summary>
        /// 启动自旋线程
        /// </summary>
        public void Start()
        {
            this._thread.Start();
        }

        /// <summary>
        /// 停止自旋线程
        /// </summary>
        public void Stop()
        {
            this._thread.Stop();
        }

        /// <summary>
        /// 释放资源
        /// </summary>
        public void Dispose()
        {
            this._thread.Dispose();
        }
    }


    /// <summary>
    /// 自旋线程动作接口
    /// </summary>
    public interface ISpinThreadAction
    {
        /// <summary>
        /// 执行动作
        /// </summary>
        void Excute();
    }
}
